﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Company.Utility.Encrypt;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using HttpContent = Microsoft.AspNetCore.Http.HttpContext;
using UEditorNetCore;
using UEditorNetCore.Handlers;

namespace Company.Utility.ImageUpload
{
    public class UeditorUploadHandle
    {
        public static void Upload(HttpContent context)
        {
            Handler action = null;
            switch (context.Request.Query["action"])
            {
                case "uploadimage":
                    action = new MyUploadHandler(context, new UploadConfig()
                    {
                        AllowExtensions = Config.GetStringList("imageAllowFiles"),
                        PathFormat = Config.GetString("imagePathFormat"),
                        SizeLimit = Config.GetInt("imageMaxSize"),
                        UploadFieldName = Config.GetString("imageFieldName")
                    });
                    break;
                default:
                    action = new NotSupportedHandler(context);
                    break;
            }
            action.Process();
        }
    }

    public class MyUploadHandler : Handler
    {

        public UploadConfig UploadConfig { get; private set; }
        public UploadResult Result { get; private set; }

        public MyUploadHandler(HttpContent context, UploadConfig config)
            : base(context)
        {
            this.UploadConfig = config;
            this.Result = new UploadResult() { State = UploadState.Unknown };
        }

        public override void Process()
        {
            string uploadFileName = null;
            var file = Request.Form.Files[UploadConfig.UploadFieldName];
            if (UploadConfig.Base64)
            {
                uploadFileName = UploadConfig.Base64Filename;
            }
            else
            {
                uploadFileName = file.FileName;
                if (!CheckFileType(uploadFileName))
                {
                    Result.State = UploadState.TypeNotAllow;
                    WriteResult();
                    return;
                }
            }

            Result.OriginFileName = uploadFileName;
            try
            {
                var result = ProxyImageServices.UploadImage(file, "UEditor", ProxyImageServices.CuteMode.W, 750, 900);
                if (result.success == false)
                {
                    throw new Exception();
                }
                else
                {
                    Result.Url = ReadConfig.ReadAppSetting("ImageUploadUrl") + result.filename;
                    Result.State = UploadState.Success;
                }

            }
            catch (Exception e)
            {
                Result.State = UploadState.FileAccessError;
                Result.ErrorMessage = e.Message;
            }
            finally
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                WriteResult();
            }
        }

        private void WriteResult()
        {
            this.WriteJson(new
            {
                state = GetStateMessage(Result.State),
                url = Result.Url,
                title = Result.OriginFileName,
                original = Result.OriginFileName,
                error = Result.ErrorMessage
            });
        }

        private string GetStateMessage(UploadState state)
        {
            switch (state)
            {
                case UploadState.Success:
                    return "SUCCESS";
                case UploadState.FileAccessError:
                    return "文件访问出错，请检查写入权限";
                case UploadState.SizeLimitExceed:
                    return "文件大小超出服务器限制";
                case UploadState.TypeNotAllow:
                    return "不允许的文件格式";
                case UploadState.NetworkError:
                    return "网络错误";
            }
            return "未知错误";
        }

        private bool CheckFileType(string filename)
        {
            var fileExtension = Path.GetExtension(filename).ToLower();
            return UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
        }
    }
}
